﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.model;
using snat.algorithms;
using System.IO;

namespace algorithms.algorithms.Example
{

public class MultiRecipientMessageCounter : IAlgorithm, ITextRenderable, IReaderWriter {

    // Implementation of IAlgorithm.Name
    public string Name {
        get { return "Multi-Recipient Message Count"; }
    }

    // Property to hold the message count
    public int MultiRecipientMessageCount { get; private set; }

    // Method to run when TapeLoaded event is thrown
    public void OnTapeLoaded() {
        MultiRecipientMessageCount = 0;
    }

    // Method to run when MessageProcessed event is thrown
    public void OnMessageProcessed(Message message) {
        // Increment counter if the message has more than one recipient
        if (message.Recipients.Count > 1) {
            MultiRecipientMessageCount++;
        }
    }

    // Method to run when TapeEnded event is thrown
    public void OnTapeEnded() {
        // Throw the event so GUI knows there is some text to be rendered
        if (RenderText != null) RenderText(this); // Check if null before throwing
    }

    // Implementation of IAlgorithm.Register, add methods to events here
    public void Register() {
        // Add the OnTapeLoaded method to the NetworkModel.TapeLoaded event
        NetworkModel.Instance.TapeLoaded += OnTapeLoaded;
        // Add the OnProcessed method to the NetworkModel.MessageProcessed event
        NetworkModel.Instance.MessageProcessed += OnMessageProcessed;
        // Add the OnTapeEnded method to the NetworkModel.TapeEnded event
        NetworkModel.Instance.TapeEnded += OnTapeEnded;
    }

    // Implementation of IAlgorithm.DeRegister, remove methods from events here
    public void DeRegister() {
        // remove the OnTapeLoaded method from the NetworkModel.TapeLoaded event
        NetworkModel.Instance.TapeLoaded -= OnTapeLoaded;
        // Remove the OnProcessed method from the NetworkModel.MessageProcessed event
        NetworkModel.Instance.MessageProcessed -= OnMessageProcessed;
        // Remove the OnTapeEnded method from the NetworkModel.TapeEnded event
        NetworkModel.Instance.TapeEnded -= OnTapeEnded;
    }

    // Implementation of IReadWriter.Write, writes algorithm data to file.
    public void Write(string filePath) {
        // Write out the count to the file at filePath to persist the result.
        using (StreamWriter output = new StreamWriter(filePath)) {
            output.WriteLine(MultiRecipientMessageCount);
        }
    }

    // Implementation of IReaderWriter.Read, reads algorithm data in and returns as String.
    public string Read(string filePath) {
        String ret = String.Empty;
        // Read in the file at filePath and return the String it contains.
        using (StreamReader input = new StreamReader(filePath)) {
            ret += input.ReadLine();
        }
        return ret;
    }
    
    // Implementation of ITextRenderable.RenderText, event listned to by the GUI
    public event RenderTextDelegate RenderText;

    // Implementation of ITextRenderable.RenderText, returns the text to be printed on the GUI console
    public string GetRenderableText() {
        return String.Format("Number of multi-recipient messages is {0}", MultiRecipientMessageCount);
    }

    
}
}
